package com.zgjl.api.util;

import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.engines.SM4Engine;
import org.bouncycastle.crypto.modes.CBCBlockCipher;
import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;

import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.Base64;

/**
 * @Author: ShenDong
 * @Date: 2024/11/10 11:28
 * @Description:
 **/
public class SM4Util {

    private static String sm4Secret;

    // 设置静态密钥
    public static void setSm4Secret(String secret) {
        SM4Util.sm4Secret = secret;
    }

    // SM4加密方法
    public static String encryptSM4(String plainText) throws Exception {
        byte[] keyBytes = Base64.getDecoder().decode(sm4Secret);

        // 随机生成 IV
        byte[] iv = new byte[16];
        new SecureRandom().nextBytes(iv);

        CipherParameters params = new ParametersWithIV(new KeyParameter(keyBytes), iv);
        PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new SM4Engine()));
        cipher.init(true, params);

        byte[] input = plainText.getBytes(StandardCharsets.UTF_8);
        byte[] encryptedBytes = new byte[cipher.getOutputSize(input.length)];
        int length = cipher.processBytes(input, 0, input.length, encryptedBytes, 0);
        length += cipher.doFinal(encryptedBytes, length);

        // 拼接 iv + 密文，一起返回
        byte[] result = new byte[iv.length + length];
        System.arraycopy(iv, 0, result, 0, iv.length);
        System.arraycopy(encryptedBytes, 0, result, iv.length, length);

        return Base64.getEncoder().encodeToString(result);
    }

    // SM4解密方法
    public static String decryptSM4(String encryptedData) throws Exception {
        byte[] keyBytes = Base64.getDecoder().decode(sm4Secret);
        byte[] data = Base64.getDecoder().decode(encryptedData);

        // 分离 IV 和密文
        byte[] iv = Arrays.copyOfRange(data, 0, 16);
        byte[] cipherBytes = Arrays.copyOfRange(data, 16, data.length);

        CipherParameters params = new ParametersWithIV(new KeyParameter(keyBytes), iv);
        PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new SM4Engine()));
        cipher.init(false, params);

        byte[] decryptedBytes = new byte[cipher.getOutputSize(cipherBytes.length)];
        int length = cipher.processBytes(cipherBytes, 0, cipherBytes.length, decryptedBytes, 0);
        length += cipher.doFinal(decryptedBytes, length);

        return new String(decryptedBytes, 0, length, StandardCharsets.UTF_8);
    }


}
